package gui;

import gui.movements.Movements;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
import players.Players;
import weapons.Weapon;
import weapons.hits.Treffer;

public class PongGui extends JPanel implements ActionListener {

    private Timer timer;
    private Players pl;
    private Players pr;
    private boolean ingame;
    private String msg;
    Image image;
    private HealthDisplay hd;
    private List<Treffer> hits = new ArrayList<>();

    public PongGui() {
        ImageIcon ii = new ImageIcon(this.getClass().getResource("Background.jpg"));
        image = ii.getImage().getScaledInstance(480, 320, 1);

        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);
        ingame = true;

        pl = new Players(0, 0, 0);
        pr = new Players(480 - 22, 0, 1);
        timer = new Timer(5, this);
        timer.start();
    }

    public void paint(Graphics g) {
        super.paint(g);
        if (ingame) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(image, 0, 0, this);
            Movements.draw(g2d, pl.getImage(), pl.getX(), pl.getY());
            Movements.draw(g2d, pr.getImage(), pr.getX(), pr.getY());

            Movements.drawProjectile(pl.getProjectiles(), g2d);
            Movements.drawProjectile(pr.getProjectiles(), g2d);


            for (int i = 0; i < hits.size(); i++) {
                hits.get(i).reduceLifetime();
                Treffer t = hits.get(i);

                if (t.getLifetime() >= 0) {
                    Movements.draw(g2d, t.getImage(), t.getX(), t.getY());
                } else {
                    hits.remove(t);
                }
            }

        } else {
            Font small = new Font("Helvetica", Font.BOLD, 14);
            FontMetrics metr = this.getFontMetrics(small);

            g.setColor(Color.white);
            g.setFont(small);
            g.drawString(msg, 50, 50);
        }

        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        List ml = pl.getProjectiles();
        List mr = pr.getProjectiles();

        for (int i = 0; i < ml.size(); i++) {
            Weapon m = (Weapon) ml.get(i);
            if (m.isVisible()) {
                m.move();
            } else {
                ml.remove(i);
            }
        }

        for (int i = 0; i < mr.size(); i++) {
            Weapon m = (Weapon) mr.get(i);
            if (m.isVisible()) {
                m.move();
            } else {
                mr.remove(i);
            }
        }
        pl.move();
        pr.move();
        checkCollisions();
        checkLoose();
        updateHealth();
        repaint();
    }

    private void checkLoose() {
        if (pl.getHealth() <= 0) {
            ingame = false;
            msg = "Game Over!\nPlayer right wins!";
        }

        if (pr.getHealth() <= 0) {
            ingame = false;
            msg = "Game Over!\nPlayer left wins!";

        }
    }

    private void updateHealth() {
        hd.updateHealth(pl.getHealth(), pr.getHealth());
    }

    private class TAdapter extends KeyAdapter {

        @Override
        public void keyReleased(KeyEvent e) {
            pl.keyReleased(e);
            pr.keyReleased(e);
        }

        @Override
        public void keyPressed(KeyEvent e) {
            pl.keyPressed(e);
            pr.keyPressed(e);
        }
    }

    public void checkCollisions() {

        List ml = pl.getProjectiles();
        List mr = pr.getProjectiles();

        for (int i = 0; i < ml.size(); i++) {
            Weapon m = (Weapon) ml.get(i);

            if (m.getBounds().intersects(pr.getBounds())) {
                pl.removeProjectile(m);
                pr.hit(m);
                hits.add(new Treffer(pr.getX(), pr.getY(), m));

            }
        }
        for (int i = 0; i < mr.size(); i++) {
            Weapon m = (Weapon) mr.get(i);


            if (m.getBounds().intersects(pl.getBounds())) {
                pr.removeProjectile(m);
                pl.hit(m);
                hits.add(new Treffer(pl.getX(), pl.getY(), m));
            }
        }
    }

    public int getPlayerLeftHealth() {
        return pl.getHealth();
    }

    public int getPlayerRightHealth() {
        return pr.getHealth();
    }

    public int getMaximumHealth() {
        return pr.getMaxHealth();
    }

    public void setHd(HealthDisplay hd) {
        this.hd = hd;
    }
}
